package cn.le.service;

import cn.le.dao.ProductDAO;
import cn.le.dao.PropertyDAO;
import cn.le.dto.PropertyDTO;
import cn.le.enums.EDataFormat;
import cn.le.po.ProductPO;
import cn.le.po.PropertyPO;
import cn.le.redis.BaseRedisUtil;
import cn.le.util.BeanUtils;
import cn.le.util.IdUtils;
import cn.le.vo.RedisProductVO;
import cn.le.vo.RedisPropertyVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
public class PropertyService {

    @Autowired
    private PropertyDAO propertyDAO;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductDAO productDAO;
    @Autowired
    private BaseRedisUtil redisUtil;

    @Transactional(rollbackFor = Exception.class)
    public void add(PropertyDTO dto){
        ProductPO productPO = productDAO.getById(dto.getProductId());
        if (productPO == null){
            throw new RuntimeException("产品不存在");
        }
        PropertyPO po = propertyDAO.getByName(dto.getProductId(),dto.getName());
        if (po != null){
            throw new RuntimeException("产品属性重复");
        }
        po = propertyDAO.getByIdentifier(dto.getProductId(),dto.getIdentifier());
        if (po != null){
            throw new RuntimeException("产品属性重复");
        }
        po = BeanUtils.copyProperties(PropertyPO.class,dto);
        po.setId(IdUtils.next());
        po.setType(dto.getType().getType());
        po.setCreateAt(new Date());
        propertyDAO.insert(po);

        this.doRedis(productPO);
    }


    private void doRedis(ProductPO productPO){
        List<PropertyPO> list = propertyDAO.findByProductId(productPO.getId());
        List<RedisPropertyVO> listVo = new ArrayList<>(list.size());
        list.forEach(po->{
            if (EDataFormat.BYTE.getFormat().equals(productPO.getFormat())){
                listVo.add(new RedisPropertyVO(po.getId(),po.getOfset()));
            }else if (EDataFormat.JSON.getFormat().equals(productPO.getFormat())){
                listVo.add(new RedisPropertyVO(po.getId(),po.getIdentifier()));
            }
        });
        RedisProductVO vo = new RedisProductVO(productPO.getFormat(),listVo);
        redisUtil.put(productPO.getId(),vo);
    }

    /**
     * 刷新数据到redis
     */
    public void refresh(){
        List<ProductPO> productList = productDAO.find();
        if (CollectionUtils.isEmpty(productList)){
            throw new RuntimeException("产品不存在");
        }
        //获取产品信息
        Map<Long,RedisProductVO> map = new HashMap<>();
        Set<Long> ids = new HashSet<>();
        productList.forEach(po->{
            ids.add(po.getId());
            map.put(po.getId(),new RedisProductVO(po.getFormat(),new ArrayList<>()));
        });
        //获取属性信息
        List<PropertyPO> propertys = propertyDAO.findByProductIds(ids);
        if (CollectionUtils.isEmpty(propertys)){
            throw new RuntimeException("产品属性不存在");
        }
        propertys.forEach(property -> {
            RedisProductVO vo = map.get(property.getProductId());
            if (EDataFormat.BYTE.getFormat().equals(vo.getFormat())) {
                vo.getPropertys().add(new RedisPropertyVO(property.getId(), property.getOfset()));
            }else if (EDataFormat.JSON.getFormat().equals(vo.getFormat())){
                vo.getPropertys().add(new RedisPropertyVO(property.getId(), property.getIdentifier()));
            }
        });
        redisUtil.putAll(map);
    }

}
